\documentclass[a4paper,11pt]{article}

\usepackage{lscape}
\usepackage{geometry}
\usepackage[utf8]{inputenc}
\usepackage[francais]{babel}
\usepackage[T1]{fontenc}
\usepackage{gantt}
\usepackage{tikz}
\usepackage{tikz-uml}
\usepackage{relsize}
\usepackage{color}
\usepackage[boxed]{algorithm2e}
\usepackage{tabularx}
\usepackage[hidelinks]{hyperref}
\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.58,0,0.82}

\usepackage{listings}
\usepackage{float}
%\usepackage{kpfonts}

\usepackage{graphicx}
%\usepackage{rotating}

\lstset{
  language=C++,
  basicstyle=\footnotesize,
  backgroundcolor=\color{white},
  keywordstyle=\color{red},
  commentstyle=\color{dkgreen},
  stringstyle=\color{mauve},
  numberstyle=\color{red},
  morekeywords={string},
  frame=BL,
  aboveskip=1em,
  belowskip=2em,
}
\lstset{
  literate={ù}{{\`u}}1
  {é}{{\'e}}1
  {è}{{\'e}}1
  {à}{{\`a}}1
}


\lstdefinelanguage{tikzuml}{language=[LaTeX]TeX, classoffset=0, morekeywords={umlbasiccomponent, umlprovidedinterface, umlrequiredinterface, umldelegateconnector, umlassemblyconnector, umlVHVassemblyconnector, umlHVHassemblyconnector, umlnote, umlusecase, umlactor, umlinherit, umlassoc, umlVHextend, umlinclude, umlstateinitial, umlbasicstate, umltrans, umlstatefinal, umlVHtrans, umlHVtrans, umldatabase, umlmulti, umlobject, umlfpart, umlcreatecall, umlclass, umlvirt, umlunicompo, umlimport, umlaggreg}, classoffset=1, morekeywords={umlcomponent, umlsystem, umlstate, umlseqdiag, umlcall, umlcallself, umlfragment, umlpackage}, classoffset=0,  sensitive=true, morecomment=[l]{\%}}

\geometry{margin=2.5cm}
\geometry{headheight=15pt}

\usepackage{fancyhdr}
\usepackage{fancyvrb}
\usepackage{float}
\usepackage[footnote,smaller]{acronym}

\pagestyle{fancy}
\rhead{RE203 - Projet de Réseau}

% \acrodef{LABRI}{Laboratoire Bordelais de Recherche en Informatique}

\begin{document}

\begin{titlepage}
  \begin{center}

    \textsc{\LARGE RE203 - Projet de Réseau}\\[2cm]
    \textsc{\large Rapport Final}\\[3cm]
    Maxime \textsc{Bellier} \ \ \ Jean-Michaël \textsc{Celerier}\\
    Julien \textsc{Chaumont} \ \ \ Bazire \textsc{Houssin} \ \ \ Sylvain \textsc{Vaglica}\\[1cm]
    \textsc{Groupe 3}\\[1.5cm]
    \textsc{\large 15/05/2013 }\\[1.5cm]
    \includegraphics[width=8cm]{logo.png}

  \end{center}
  \vspace{3cm}

\end{titlepage}

\clearpage

\section*{Introduction}

Ce rapport final pour le projet de réseau RE203 fait suite au rapport intermédiaire délivré le 23 avril dernier. Il sera ici question de l'implémentation mise en \oe uvre par notre groupe, l'explication du sujet ayant été développée précédemment.

\section{Le bloc commun}

Étant donné que le développement des deux parties du projet (contrôleur et routeur) a été réalisé respectivement dans les langages C et C++, il a été décidé d'établir une sorte bibliothèque commune sur laquelle se baser. Cette partie comprend:
\begin{itemize}
 \item une invite de commande
 \item un système de gestion des fichiers de configuration
 \item des fonctions de traitement des messages reçus et à envoyer
 \item une API pour la gestion des sockets
 \item quelques fonctions utilitaires
\end{itemize}

Chacun de ces blocs est indépendant des autres, ce qui assure une intégration facilitée dans le contrôleur comme dans le routeur. Une telle organisation permet d'introduire un certain degré d'abstraction tout en limitant la redondance
de code entre les deux composantes du projet.

\subsection{Le prompt}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{common/prompt.c}, \texttt{common/prompt.h}
\end{tabularx}\\

L'invite de commande, ou \textit{prompt} en Anglais, permet la communication entre le contrôleur ou le routeur, et l'utilisateur. Il suffit pour cela de regarder constamment sur l'entrée standard et de traiter les commandes saisies par l'utilisateur. Afin de ne pas bloquer le programme sur l'écoute du fichier \texttt{stdin}, il faut pouvoir exécuter cette tâche en parallèle, d'où l'utilisation de la bibliothèque \texttt{pthread} ici.

Les fonctions définies dans les fichiers sus-mentionnés assurent la création de ce thread et l'écoute sur l'entrée standard. Le paramètre à fournir à la fonction d'initialisation est un pointeur de fonction. Lorsqu'une information arrive, elle est mise en mémoire et convertie en un \texttt{Message}\footnote{Se référer à la partie \ref{message}}, et c'est à la fonction dont le pointeur est passé en paramètre de gérer les actions à effectuer suite à la réception de ce message.

De cette manière, contrôleur et routeur ont seulement à gérer la fonction de traitement des messages utilisateur (chaque programme devant comprendre des commandes qui lui sont spécifiques), mais la tâche de récupération des instructions de l'utilisateur est quant à elle unifiée.

\subsection{Traitement des fichiers de configuration}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{common/config.c}, \texttt{common/config.h}
\end{tabularx}\\

Le sujet demandait à ce que routeur comme contrôleur puissent être paramétrés depuis un fichier de configuration. Ce module permet la lecture de ces fichiers. La bibliothèque C \texttt{T-Rex}\footnote{Publiée sous licence libre \textit{zlib} par Alberto Demichelis, consultable à l'adresse \url{http://sourceforge.net/projects/tiny-rex/}}, qui permet la manipulation d'expressions régulières, a été utilisée dans ce cadre afin de faciliter la reconnaissance des différentes lignes possibles dans les fichiers de configuration.

Dans le code du routeur (respectivement du contrôleur), il suffit d'appeler la fonction \texttt{config\_\_readRouter} (respectivement \texttt{config\_\_readController}). En interne, ces fonctions ouvrent le fichier de configuration indiqué, le lisent ligne par ligne, identifient les mots-clés à l'aide des expressions régulières, et remplissent une variable de type \texttt{Configuration} avec les informations contenues dans le fichier. Cette structure de données est déclarée de la manière suivante:

\begin{lstlisting}
enum SoftwareType { ROUTER, CONTROLLER };

typedef struct Configuration
{
	enum SoftwareType type;
	char controllerAddress[20];
	int  routerPort;
	int  controllerPort;
	int  pollTimeoutValue;
	int  controllerUpdateInterval;
	int  routerUpdateInterval;
	int  defaultTTLValue;
	int  defaultPingPacketCount;
	int  defaultPacketTimeoutValue;
	int  defaultDVTimeoutValue;
} Configuration;
\end{lstlisting}

A la fin de la lecture, il ne reste plus qu'à retourner au programme appelant un pointeur vers la structure remplie, qui n'aura alors qu'à consulter la valeur de ces différents attributs.

Notez que la structure \texttt{Configuration} contient des attributs concernant aussi bien le contrôleur que le routeur. C'est au programme de veiller à n'utiliser que les attributs le concernant, les autres attributs n'ayant aucune garantie d'avoir été initialisés à une valeur cohérente (précisons cependant qu'il n'y a aucune raison pour que le contrôleur ait besoin des informations propres aux routeurs, et inversement).

\subsection{Le système des \texttt{Messages}}
\label{message}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{common/messages.c}, \texttt{common/messages.h}\\
\end{tabularx}\\

Les \texttt{Messages} correspondent à une structure de données relative aux informations reçues et transmises par le contrôleur, le routeur ou l'utilisateur. Ce module permet notamment:
\begin{itemize}
 \item L'allocation et la libération dynamique d'un message
 \item L'échappement d'une chaîne de caractères (caractères "*" et "\textbackslash"), à utiliser lors de l'envoi d'un \texttt{Message}, et l'opération inverse pour la réception
 \item Le parsing, c'est-à-dire la reconnaissance de la commande contenue dans le \texttt{Message} (là aussi, la bibliothèque \texttt{T-Rex} est mise à contribution)
 \item La gestion du TTL
\end{itemize}
La structure \texttt{Message} contient toutes les informations nécessaires au traitement ultérieur.

\begin{lstlisting}
typedef struct Message
{
	enum MessageType type;  //Type du message (login, poll, ping, load, ...)
	char *s_parameter;      //Paramètre de la commande (identifiants, ...)
	int  n_parameter;       //Paramètre de la commande (numéro de port, ...)
	char *node1, *node2;    //Identifiants de l'émetteur et du récepteur
	int  seqnum;            //Numéro de séquence
	enum Acceptance accept; //Type de retour
} Message;
\end{lstlisting}

\subsection{La gestion des sockets}

\subsubsection{La structure \texttt{Client}}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{common/client.c}, \texttt{common/client.h}\\
\end{tabularx}\\

La structure \texttt{Client} sert de base à la gestion des communications par socket. Elle permet l'association d'un routeur par son identifiant à une socket (qui contient à la fois l'adresse IP et le port à utiliser pour établir une communication avec ce client). Les fonctions fournies avec ce module permettent la récupération du port, de l'adresse et de l'identifiant d'un client, la mise à jour de l'identifiant ou encore la comparaison de deux \texttt{Client}s.

La fonction \texttt{getsockname} de la bibliothèque \texttt{sys/socket.h}, en addition des fonctions \texttt{inet\_ntoa} et \texttt{ntohs}, permet de récupérer séparément, et sans difficulté majeure, l'adresse et le numéro de port depuis une socket.

\subsubsection{Les sockets}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{common/net.c}, \texttt{common/net.h}, \texttt{common/sock.h}\\
\end{tabularx}\\

Il s'agit certainement du pilier du projet, puisque c'est ce module qui assure la communication entre les routeurs et/ou le contrôleur en réseau. L'idée était en fait de réaliser une couche d'abstraction au-dessus de la bibliothèque \texttt{sys/socket.h}.

La structure de données utilisée ici se nomme \texttt{network}, et représente le réseau.
\begin{lstlisting}
struct network_s{
  short status; //Réseau ouvert ou fermé
  SOCKET server;//Socket du serveur
  int max;      //Plus grand identifiant de socket (utilisé par select)
  Client *clients; //Clients connectés
  unsigned int nb_clients; //Taille du tableau précédent

  /* Fonctions d'événement */
  //Fonction à appeler lorsque l'entrée standard a été utilisée
  input_event_function input_event;
  //Fonction à appeler lors de la connexion d'un client
  connection_event_function connection_event;
  //Fonction à appeler lors de la déconnexion d'un client
  disconnection_event_function disconnection_event;
  //Fonction à appeler lors de la réception d'un message
  message_event_function message_event;
};
\end{lstlisting}

Une fois les fonctions d'initialisation appelées, la fonction \texttt{network\_\_update} permet l'écoute \textit{non bloquante} (à l'aide de la fonction de multiplexage de la librairie standard \texttt{select}) sur le port indiqué. A chaque événement (\textit{ie} connexion ou déconnexion d'un client, réception d'un message, \dots), la fonction continue le traitement en analysant le type de l'événement qui l'aura réveillé et en appelant les fonctions correspondantes dont les pointeurs sont indiqués dans la structure \texttt{network} utilisée. Ce sera le rôle de ces fonctions de gérer les actions à mettre en place, ce qui dépend évidemment de s'il s'agit du contrôleur ou d'un routeur, et doivent donc être implémentées et initialisées directement depuis le programme utilisant le module.

\newpage
\section{Le contrôleur}

En se basant sur le code du bloc commun, il est plus facile d'écrire un code propre et bien organisé. Cette seconde partie détaille l'implémentation du contrôleur.

\subsection{Gestion des graphes}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{controller/graphlib.c}, \texttt{controller/graphlib.h}\\
\end{tabularx}\\

La première action à effectuer sur le contrôleur est le chargement de la topologie d'un réseau sous la forme d'un fichier au format \textit{dot}. A cet effet, il a fallu mettre en place un système de gestion de graphes facilitant les interactions entre le format \textit{dot} et la représentation en mémoire: la librairie de graphes de \textit{graphviz}\footnote{Publiée sous licence libre Eclipse, consultable à l'adresse \url{http://www.graphviz.org/}} était incontestablement la plus apte à répondre à ce problème. Dans un souci de propreté du code, une couche d'abstraction a été, ici aussi, mise en place au dessus de \textit{graphviz}.

Dans la pratique, le programme agit sur une variable globale de type \texttt{Agraph\_t}. Cette structure contient en fait l'arbre correspondant à la topologie du réseau chargé, où chaque n\oe ud est un routeur, et où chaque arête indique le voisinage de deux routeurs et est labellisée du poids du chemin représenté. \textit{graphviz} offre toutes les fonctions nécessaires au traitement d'une telle variable, de son initialisation à l'aide d'un fichier \textit{.dot} à sa sauvegarde, et évidemment l'ajout/suppression/modification de tout n\oe ud ou arête.

\subsection{Table des routeurs}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{controller/info\_table.c}, \texttt{controller/info\_table.h}\\
\end{tabularx}\\

Un structure de table de hachage est utilisée dans le code du contrôleur. Son rôle est de faire le lien entre l'identifiant d'un routeur (son nom) et la structure \texttt{Client} qui lui est associée et qui permet la communication. Pour cela, cette partie du code source se base sur la bibliothèque \textit{Hash-Table}\footnote{Publiée sous licence libre GNU/GPL par Ankur Shrivastava, consultable à l'adresse \url{https://github.com/ankurs/Hash-Table/}} en C, qui a le grand avantage d'être très simple d'utilisation, en plus d'avoir une documentation bien exhaustive. Après initialisation de la structure, celle-ci est mise à jour à chaque connexion et déconnexion d'un routeur sur le réseau. Dans le cas d'une connexion, rappelons que le bloc de gestion des sockets gère de lui-même l'allocation et l'initialisation d'une structure \texttt{Client}.

Travailler sur une telle structure de données permet d'optimiser la complexité temporelle de la recherche des informations de connexion d'un routeur donné. Comme pour le graphe du réseau, le contrôleur travaille sur une variable globale pour gérer la table de hachage.

\subsection{Traitement des commandes}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{controller/exec.c}, \texttt{controller/exec.h}\\
\end{tabularx}\\

Comme évoqué précédemment, les commandes envoyées par l'utilisateur et par les routeurs sont respectivement réceptionnées par le \textit{prompt} et par le module de gestion des sockets.
Le code propre au contrôleur doit ensuite être capable de traiter ces commandes.

Pour cela, les deux fonctions \texttt{exec\_\_prompt\_message} et \texttt{exec\_\_sock\_message}, appelés par les modules sus-cités, ont pour rôle de traiter l'action demandée, à savoir:
\begin{itemize}
 \item Dans le cadre d'un message venant du \textit{prompt}:
 \begin{itemize}
  \item[$\bullet$] Chargement de la topologie du réseau depuis un fichier vers une structure de graphe
  \item[$\bullet$] Enregistrement de la structure de graphe courante dans un fichier
  \item[$\bullet$] Affichage du graphe du réseau dans le terminal
  \item[$\bullet$] Ajout/modification/suppression d'une connexion dans le graphe du réseau
  \item[$\bullet$] Déconnexion d'un routeur
  \item[$\bullet$] Demande de l'arrêt du contrôleur
 \end{itemize}
 \item Dans le cadre d'un message venant d'une socket:
 \begin{itemize}
  \item[$\bullet$] Connexion d'un routeur
  \item[$\bullet$] Demande de \textit{poll}
  \item[$\bullet$] Déconnexion d'un routeur
 \end{itemize}
\end{itemize}
Ces fonctions se chargent simplement, selon la nature de la demande, d'appeler les fonctions des autres modules
(par exemple l'ajout d'une arête dans le graphe lors de la demande d'ajout d'une connexion entre deux routeurs, ou encore l'ajout des informations de connexion d'un routeur à la table de hachage lors de la connexion d'un routeur au réseau), en faisant dans certains cas quelques vérifications d'intégrité (est-ce que le routeur indiqué existe? le pointeur passé en paramètre est-il valide? \dots).

\subsubsection*{Précisions sur la demande de \textit{poll}}

Le \textit{poll}, qui consiste à renvoyer au routeur appelant la liste de ses voisins ainsi que le coût de leurs liaisons respectives, utilise directement le graphe du réseau. Pour construire cette liste, il faut parcourir la liste des voisins du routeur dans le graphe. La librairie \textit{graphviz} facilite cette opération en proposant des fonctions de parcours des arêtes d'un sommet donné (initialisation avec \texttt{agfstedge}, puis parcours avec \texttt{agnxtedge}). Il ne reste plus qu'à récupérer le nom du sommet au bout de l'arête courante, le poids de ladite arête, et concaténer le tout selon la syntaxe demandée.

Notons tout de même que, même si la topologie chargée indique la propriété de voisinage sur deux routeurs donnés, il se peut que le second routeur ne se soit pas encore connecté au réseau. Dans ce cas, il ne faut pas l'ajouter au voisinage puisque celui-ci est, pour une durée indéterminée, injoignable. Cette difficulté est aisément contournée en ajoutant une information booléenne dans chaque n\oe ud du graphe, indiquant si oui ou non le routeur associé est connecté (initialisé à $0$ puis mis à $1$ lors de la connexion, et enfin à $0$ lors de la déconnexion).

Le sujet précise également que la liste retournée doit être nulle si le voisinage du routeur n'a pas été modifié depuis le dernier \textit{poll}. Pour vérifier cette propriété, on utilise là aussi une information booléenne dans chaque n\oe ud du graphe, qui précise si le voisinage du routeur associé a été ou non modifié depuis la dernière demande de mise à jour. Celle-ci est d'abord mise à $0$ avant le premier \textit{poll}, puis à $1$ après chaque nouvelle demande. La mise à $0$ est également effectuée sur tous les routeurs voisins d'un routeur venant de se connecter ou de se déconnecter, ainsi que sur tous les routeurs concernés par un ajout, suppression ou modification d'arête. De cette façon, il n'y a qu'à vérifier la valeur de ce booléen pour savoir si la procédure doit être faite en entier, ou s'il suffit de renvoyer une liste vide.

\subsection{Résumé du fonctionnement du contrôleur}

L'algorithme suivant résume brièvement le fonctionnement du contrôleur. L'intégralité du traitement des commandes, de la réception à l'exécution puis à la génération de la réponse, est exécuté dans les différents sous-modules.
\\
\begin{algorithm}[H]
 initialization(graph, hash\_table, network)\;
 \While{is\_opened(network)} {
    \tcc{these instructions are executed in a separated thread}
 	message = prompt\_\_new\_message()\;
 	\If{message\_\_is\_not\_empty(message) $ {\bf and} $ message\_\_is\_valid(message)}{
 		exec\_\_prompt\_message(message)\;
 	}
 	\BlankLine
 	\tcc{and these ones are executed in the main thread}
 	message = network\_\_new\_message()\;
 	\If{message\_\_is\_not\_empty(message) $ {\bf and} $ message\_\_is\_valid(message)}{
 		exec\_\_network\_message(message)\;
 	}
 	\BlankLine
 	\tcc{in this way, both are executed in the same time without creating any deadlock}
 }
 close(graph, hash\_table, network)\;
\end{algorithm}

\section{Les routeurs}

De même que pour le contrôleur, une partie du code du routeur se base sur le code commun présenté précédemment. Néanmoins, le défi repose dans le fait que le routeur est écrit en C++, et que bien qu'il y ait un fort lien de parenté entre les deux langages, il est parfois nécessaire de connaître quelques astuces pour pouvoir interfacer les deux codes.

De plus, il a été fait en sorte que le code suive une architecture MVC (Modèle-Vue-Contrôleur), en séparant les classes qui servent
à l'entrée/sortie et celles qui servent à la gestion du logiciel. La majorité des appels passe par une classe contrôleur.

\subsection{La classe Router}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{router/router.cpp}, \texttt{router/router.hpp}\\
\underline{Classe :} & \texttt{Router}\\
\end{tabularx}\\

Cette classe est la classe principale du programme. Elle est instanciée dans le \textit{main}, et instancie par la suite toutes les autres
classes du logiciel; c'est le contrôleur (au sens MVC) du logiciel.

La classe \texttt{Router} contient notamment la table de routage, ainsi que la plupart des classes qui gèrent les messages, et manipule les threads
qui servent à communiquer périodiquement avec le contrôleur et les autres routeurs, par le biais des commandes \textit{poll} et \textit{vector}).

\subsection{La table de routage : RouteTable}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{router/routetable.cpp}, \texttt{router/routetable.hpp}, \texttt{router/entry.cpp}, \texttt{router/entry.hpp}\\
\underline{Classes :} & \texttt{Router}, \texttt{Entry}\\
\end{tabularx}\\

La table de routage a été implémentée sur la base d'un simple tableau associatif (l'objet \texttt{map} du C++).
Pour un routeur donné, on associe à chacun de ses voisins (désigné par son nom) une structure \texttt{Entry} qui contient les différentes informations nécessaires
à la communication avec ce client.

\texttt{Entry} contient un pointeur vers un \texttt{Client}, présenté précédemment, la distance entre deux n\oe uds, ainsi que
le prochain saut à effectuer pour rejoindre un n\oe ud.

\subsection{Gestion des messages}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{router/event.cpp}, \texttt{router/event.hpp}, \texttt{router/exec.cpp}, \texttt{router/exec.hpp}\\
\underline{Classes :} & \texttt{Event}, \texttt{Exec}\\
\end{tabularx}\\

Grâce à l'architecture choisie, la gestion de la communication est sensiblement semblable à celle utilisée dans le routeur.

Le prompt (classe\texttt{Prompt}), ainsi que la pseudo-classe \texttt{net} de la partie commune, communiquent avec la classe \texttt{Exec},
 qui est chargée de la compréhension et de l'application des actions requises lors de la réception d'un message.

L'utilisation du même système d'événements qu'en C a posé des problèmes d'incompatibilité de prototypes: en effet,
la classe \texttt{Event} contient les événements à exécuter en cas d'opération sur le réseau; mais le prototype attendu par la fonction C
est incompatible avec une méthode d'instance, qui contient un paramètre caché \texttt{this}.

Il a donc été nécessaire d'avoir une variable globale vers la classe \texttt{Router} pour accéder à toutes les informations nécessaires (table de routage en particulier) dans la classe \texttt{Event}. Ce n'est certes pas une bonne pratique de programmation, mais cela permet de n'avoir qu'un seul code pour le routeur et le contrôleur.

Pour information, les messages à gérer au prompt sont \textit{ping}, \textit{route} et \textit{message}, mais d'autres ont été ajoutés, tels que \textit{quit} pour quitter le logiciel, et \textit{poll} pour forcer la mise à jour du voisinage.

\texttt{Exec} contient la logique des opérations à réaliser (par exemple, si le message est de type \texttt{neighborhood} et que son niveau d'acceptation est \texttt{OK}, alors on ne fait rien, sinon on fait le traitement nécessaire sur le message). Mais la plus grande partie du traitement se déroule dans des classes séparées : \texttt{PromptActions} et \texttt{SockActions}. \texttt{PromptActions} contient les actions à réaliser pour un message rentré à la main, et \texttt{SockActions} en fait de même pour un message reçu par le réseau.

A la différence de \texttt{Exec}, ces deux classes manipulent directement les fonctions contenues dans \texttt{net.c}.
Ce sont elles qui forment les messages à envoyer par le réseau, en remplissant notamment les membres de la structure Message.

\subsection{Classes annexes}

\begin{tabularx}{\linewidth}{lX}
\underline{Fichiers :} & \texttt{router/display.cpp}, \texttt{router/display.hpp}, \texttt{router/exceptions.hpp}\\
\underline{Classe :} & \texttt{Display}, \texttt{Exceptions diverses et variées}\\
\end{tabularx}\\

\texttt{Display} sert à l'affichage des données du programme, des réponses aux messages, des messages d'erreurs, tel que spécifié dans le sujet.
\texttt{Exceptions} est une liste de dérivés de \texttt{std::exception}, instanciés de manière à pouvoir s'en servir très simplement; et se trouve être entièrement contenue dans un fichier header.

Par exemple, voici l'utilisation de l'exception pour l'absence d'un routeur dans la table de routage: \texttt{Unknown destination} (la casse est importante).
\\
\verb[ throw unknownDest; // envoi [\\
\verb[ catch(UnknownDest&) // récupération [\\
% ]
La gestion des exceptions de cette manière ajoute à la clarté du code.

\subsection{Diagramme de classes}

Afin de récapituler plus simplement cette partie, le diagramme de classes du routeur est donné en figure \ref{diagclasses}.

\begin{figure}[H]
\begin{center}
\begin{tikzpicture}
\umlclass[x=0, y=0]{Router}{
}{}
\umlclass[x=-2, y=2]{Prompt}{
}{}
\umlclass[x=0, y=-2]{Event}{
}{}
\umlclass[x=3, y=2]{Exec}{
}{}
\umlclass[x=6, y=2]{Display}{
}{}
\umlclass[x=4, y=0]{PromptActions}{
}{}
\umlclass[x=3, y=-2]{SockActions}{
}{}
\umlclass[x=-3, y=-2]{RouteTable}{
}{}
\umlclass[x=-3, y=-5]{Entry}{
}{}

\umlunicompo[]{Router}{Prompt}
\umlunicompo[]{Router}{Event}
\umlunicompo[]{Router}{Exec}
\umlunicompo[]{Router}{PromptActions}
\umlunicompo[]{Router}{SockActions}
\umlunicompo[]{Router}{RouteTable}

\umlunicompo[]{Exec}{Display}
\umlunicompo[mult=1..*]{RouteTable}{Entry}
\end{tikzpicture}
\caption{Diagramme de classes du routeur}
\label{diagclasses}
\end{center}
\end{figure}


\section*{Conclusion}

Les programmes proposés répondent aux différents prérequis du sujet, ce qui était à vrai dire l'objectif principal. Durant le développement, l'accent a notamment été mis sur le soin à apporter au code. En conséquence, le code source suit une architecture MVC, est documenté, et même optimisé en ce qui concerne la redondance de code (grâce au code commun aux deux sous-programmes). Cette organisation du code a aussi permis de mieux organiser l'équipe sur les différentes tâches à réaliser, et ce, bien plus finement qu'une simple répartition "routeur-contrôleur".

Par ailleurs, les tests effectués, sur un même ordinateur comme sur plusieurs en réseau, ont démontré la stabilité et la fonctionnalité du projet.


%tests, valgrind, réponse au sujet, code propre
\end{document}
